const passport = require('passport');
const httpStatus = require('http-status');
const ApiError = require('../utils/ApiError');
const { roleRights } = require('../config/roles');
const logger = require('../config/logger');

/**
 * 验证JWT，如果请求是有效的，将user设置为req.user
 * @param {Object} req - 请求对象
 * @param {Object} res - 响应对象
 * @param {Function} next - 下一个中间件函数
 * @param {Function} resolve - Promise解析函数
 * @param {Function} reject - Promise拒绝函数
 */
const verifyCallback = (req, resolve, reject) => async (err, user, info) => {
  const logData = {
    hasError: !!err,
    errorMessage: err ? err.message : null,
    hasInfo: !!info,
    infoMessage: info ? info.message : null,
    hasUser: !!user,
    authHeader: req.headers.authorization
  };
  
  logger.info(`JWT验证回调： ${JSON.stringify(logData)}`);
  console.log('JWT验证回调：', logData);
  
  if (err || info || !user) {
    return reject(new ApiError(httpStatus.UNAUTHORIZED, '请登录'));
  }
  req.user = user;
  
  const userInfo = {
    userId: user.id,
    isAdmin: !!user.isAdmin,
    permissions: user.permissions || []
  };
  
  logger.info(`用户验证成功，用户信息： ${JSON.stringify(userInfo)}`);
  console.log('用户验证成功，用户信息：', userInfo);
  
  resolve();
};

/**
 * 要求用户已通过身份验证的中间件
 * @returns {Function} Express中间件
 */
const auth = () => async (req, res, next) => {
  const requestInfo = {
    authorization: req.headers.authorization,
    path: req.path,
    method: req.method
  };
  
  logger.info(`收到请求，验证认证状态，请求头： ${JSON.stringify(requestInfo)}`);
  console.log('收到请求，验证认证状态，请求头：', requestInfo);
  
  if (req.headers.authorization && req.headers.authorization.startsWith('Bearer ')) {
    const token = req.headers.authorization.substring(7);
    try {
      const decoded = require('jsonwebtoken').decode(token);
      if (decoded) {
        logger.info(`JWT载荷： ${JSON.stringify(decoded)}`);
        console.log('JWT载荷：', decoded);
      }
    } catch (error) {
      logger.error(`解析JWT失败: ${error.message}`);
    }
  }
  
  return new Promise((resolve, reject) => {
    passport.authenticate('jwt', { session: false }, verifyCallback(req, resolve, reject))(req, res, next);
  })
    .then(() => next())
    .catch((err) => next(err));
};

/**
 * 检查用户是否有权限的函数
 * @param {Array} requiredRights - 所需权限列表
 * @returns {Function} Express中间件
 */
const authorize = (requiredRights) => async (req, res, next) => {
  logger.info(`验证权限，所需权限： ${JSON.stringify(requiredRights)}`);
  console.log('验证权限，所需权限：', requiredRights);
  
  if (!req.user) {
    logger.warn('权限验证失败：用户未登录');
    console.log('权限验证失败：用户未登录');
    return next(new ApiError(httpStatus.UNAUTHORIZED, '请登录'));
  }

  // 权限映射表
  const permissionMap = {
    'admin': 'all',
    'manageUsers': 'user_manage',
    'manageContent': 'content_manage',
    'manageSystem': 'system_config'
  };

  // 将请求的权限转换为实际的权限名称
  const mappedRequiredRights = requiredRights.map(right => permissionMap[right] || right);
  
  logger.info(`映射后的所需权限： ${JSON.stringify(mappedRequiredRights)}`);
  console.log('映射后的所需权限：', mappedRequiredRights);

  // 检查是否为管理员
  if (req.user.isAdmin) {
    // 管理员权限检查
    logger.info(`管理员权限检查，拥有权限： ${JSON.stringify(req.user.permissions || [])}`);
    console.log('管理员权限检查，拥有权限：', req.user.permissions || []);
    
    if (req.user.id) {
      logger.info(`验证管理员通过，ID: ${req.user.id}`);
      console.log('验证管理员通过，ID:', req.user.id);
    }
    
    if (!req.user.permissions) {
      logger.warn('权限验证失败：管理员没有任何权限');
      console.log('权限验证失败：管理员没有任何权限');
      return next(new ApiError(httpStatus.FORBIDDEN, '无权限执行此操作'));
    }
    
    // 检查是否有'all'权限，如果有，直接通过
    if (req.user.permissions.includes('all')) {
      logger.info('超级管理员权限检测到，直接通过验证');
      console.log('超级管理员权限检测到，直接通过验证');
      return next();
    }
    
    if (mappedRequiredRights.length) {
      // 检查是否包含所有所需权限
      const hasRequiredRights = mappedRequiredRights.every((requiredRight) => 
        req.user.permissions.includes(requiredRight));
      
      logger.info(`权限验证结果： ${hasRequiredRights ? '通过' : '失败'}`);
      console.log('权限验证结果：', hasRequiredRights ? '通过' : '失败');
      
      if (!hasRequiredRights) {
        return next(new ApiError(httpStatus.FORBIDDEN, '无权限执行此操作'));
      }
    }
  } else {
    // 普通用户权限检查
    const userRights = roleRights.get(req.user.role);
    logger.info(`普通用户权限检查，角色： ${req.user.role}，拥有权限： ${JSON.stringify(userRights || [])}`);
    console.log('普通用户权限检查，角色：', req.user.role, '拥有权限：', userRights || []);
    
    if (mappedRequiredRights.length) {
      const hasRequiredRights = mappedRequiredRights.every((requiredRight) => userRights.includes(requiredRight));
      
      logger.info(`权限验证结果： ${hasRequiredRights ? '通过' : '失败'}`);
      console.log('权限验证结果：', hasRequiredRights ? '通过' : '失败');
      
      if (!hasRequiredRights) {
        return next(new ApiError(httpStatus.FORBIDDEN, '无权限执行此操作'));
      }
    }
  }

  logger.info('权限验证通过');
  console.log('权限验证通过');
  next();
};

module.exports = {
  auth,
  authorize,
}; 